import FirstTitle from "@/components/FirstTitle";
import SubTitle from "@/components/subTitle";
import { Description } from "@/components/description";
import { Divider } from "antd";
import mc from "./index.module.scss";
import Code from "@/components/code";
import { Fragment, useRef } from "react";
import { requireImg } from "@/utils/common.ts";

export const Monitoring = () => {
  const jsmpegRef: any = useRef(null);
  const toJsmpeg = () => {
    const top = jsmpegRef.current.offsetTop + 200;
    const parent = document.getElementById("content-parent") as HTMLElement;
    parent.scrollTo({
      top: top,
      behavior: "smooth",
    });
  };
  return (
    <>
      <FirstTitle title="监控对接方式 学习" />
      <SubTitle title="rtsp 方式" />

      <Description
        info={
          <>
            <span>基于 rtsp 方式的视频流有两种对接形式</span>

            <span className={mc["t-1"]}>1. 前端启服务自己转码</span>
            <div className={mc["t-2"]}>
              1 基于 ffmpeg 的 Node 后端推流方案 + 基于 jspmeg 的前端视频展示
            </div>
            <div className={mc["t-3"]} style={{ color: "red" }}>
              *必须在系统里安装 FFMPEG，因为 RTSP 流转 WebSocket
              就是通过底层调用 FFMPEG 来实现的
            </div>
            <div className={mc["t-3"]}>
              1.1 基于 ffmpeg 的 Node 后端推流方案 + 基于 jspmeg 的前端视频展示
            </div>

            <div className={mc["t-4"]}>
              (1) 先说 node-rtsp-stream 缺点: 一个服务只能一个视频流
              <Code content={`npm i node-rtsp-stream`} type={"npm"}></Code>
            </div>
            <div className={mc["t-4"]}>(2) 启动 node-rtsp-stream</div>
            <div className={mc["t-4"]}>
              <Code
                content={`const Stream = require('node-rtsp-stream');
// Name of the stream, used to identify it in the API
new Stream({
  name: 'socket',
  streamUrl: 'rtsp://10.9.33.85:554/44030001451187000051_34020000001320000007',
  wsPort: 9999,
  // ffmpeg 的一些配置参数，比如转换分辨率等，大家可以去 ffmpeg 官网自行查询
  ffmpegOptions: {
    '-stats': '',
    '-r': 20,
    '-s': '1280 720'
  }
});`}
              ></Code>
            </div>
            <div className={mc["t-4"]}>
              (3) 启动 node 服务
              <Code content={`node 上面的文件名称.js`} type={"npm"}></Code>
            </div>
            <div className={mc["t-4"]} ref={jsmpegRef}>
              (4) 前端使用 jsmpeg 进行播放
              <Code
                content={`// 引入
<script src="https://jsmpeg.com/jsmpeg.min.js" charset="utf-8" ></script>`}
              ></Code>
            </div>
            <div className={mc["t-4"]}>
              (5) 使用canvas包裹
              <Code
                content={`<canvas
      id="canvas"
      style="width: 300px; height: 200px"
    ></canvas>`}
              ></Code>
            </div>
            <div className={mc["t-4"]}>
              (6) 调用 new JSMpeg.Player 播放
              <Code
                content={`// 改成你的rtsp流
var rtsp = 'rtsp://10.9.33.85:554/44030001451187000051_34020000001320000007'
new JSMpeg.Player('ws://localhost:9999', {
   canvas: document.getElementById('canvas' + i),
})`}
              ></Code>
            </div>
            <Divider>分界线哇</Divider>
            <div className={mc["t-3"]}>
              1.2 基于 ffmpeg 的 Node 后端推流方案 + 基于 jspmeg 的前端视频展示
            </div>
            <div className={mc["t-4"]}>
              (1) 使用 rtsp2web.js 进行转码 会有水印 可用本地的无水印版本
              <Code content={`npm i rtsp2web`} type={"npm"}></Code>
            </div>
            <div className={mc["t-4"]}>
              (2) 使用 rtsp2web.js
              <Code
                content={`const RTSP2web = require('rtsp2web')

// 服务端长连接占据的端口号；端口号可以自定义
const port = 9999
new RTSP2web({ port })`}
              ></Code>
            </div>
            <div className={mc["t-4"]}>
              (3) <a onClick={toJsmpeg}>前端使用jsmpeg 用法看上部分</a>
            </div>

            <Divider>分界线哇</Divider>
            <div className={mc["t-3"]}>1.3 基于 WebRTC 的推流方案</div>
            <div className={mc["t-4"]}>
              (1) 基于 WebRTC 实现 RTSP 流的推送，需要优先下载 webrtc-streamer
              <br />
              <a href="https://github.com/mpromonet/webrtc-streamer">
                git 地址
              </a>
            </div>
            <div className={mc["t-4"]}>
              (2) 前端使用 video 标签即可
              <Code
                content={
                  "<video id='vId' muted autoplay loop controls width='100%' height='100%'></video>"
                }
              ></Code>
            </div>
            <div className={mc["t-4"]}>
              (3) playVideo 方法播放
              <Code
                content={
                  "let webRtcServer: any = null;" +
                  "// webrtc启动的地址" +
                  "const url = 'http://10.1.18.103:9999';\n" +
                  "webRtcServer = new WebRtcStreamer(props.id, url);\n" +
                  "webRtcServer.connect(\n" +
                  "    'rtsp://admin:Zgtdzjfgs@183.237.37.51:11554/Streaming/Channels/102',\n" +
                  "    null,\n" +
                  '    "rtptransport=tcp&timeout=60",\n' +
                  "    null\n" +
                  ");"
                }
              ></Code>
            </div>
            <div className={mc["t-4"]}>
              (4) 清除方法
              <Code
                content={
                  "webRtcServer.disconnect();\n" + "webRtcServer = null;"
                }
              ></Code>
            </div>
          </>
        }
      />

      <SubTitle title="海康 ws 方式" />
      <Description
        info={
          <>
            <span className={mc["t-1"]}>1. 从后端获取ws流</span>
            <span className={mc["t-1"]}>
              2. 使用海康的 h5Player
              <img
                style={{ width: "100%", margin: "10px 0" }}
                src={requireImg("h5player下载.png")}
                alt=""
              />
            </span>
            <span className={mc["t-1"]}>
              3. 引入包
              <Code
                content={
                  '<script type="module" src="/h5player/h5player.min.js"></script>'
                }
              ></Code>
            </span>
            <span className={mc["t-1"]}>
              4. 创建容器
              <Code content={'<div id="player"></div>'}></Code>
            </span>
            <span className={mc["t-1"]}>
              5. 初始化
              <Code
                content={`player = null
player = new JSPlugin({
    szId:'player',
    szBasePath:'/h5player/',
    iMaxSplit:2,
    iCurrentSplit:1,
    openDebug: true,
})
let mode = 0
let url = 'ws://xxxxxx'
player.JS_Play(url, {url, mode},0).then(()=>{
  () => { console.log('播放成功') },
  (err)=>{
    console.error(err,'播放失败!')
  }
})`}
              ></Code>
            </span>
          </>
        }
      ></Description>

      <SubTitle title="flv 方式" />
      <Description
        info={
          <>
            <span className={mc["t-1"]}>1. 从后端获取flv流</span>
            <span className={mc["t-1"]}>
              2. 安装 flv.js
              <Code
                content={'<span className={mc["t-1"]}>1. 从后端获取ws流</span>'}
                type={"npm"}
              ></Code>
            </span>
            <span className={mc["t-1"]}>
              3. 创建容器
              <Code
                content={
                  "<video id='vId' muted autoplay loop controls width='100%' height='100%'></video>"
                }
              ></Code>
            </span>
            <span className={mc["t-1"]}>
              4. 初始化
              <Code
                content={`import flvjs from 'flv.js/dist/flv.min.js'
webrtcPlay() {
    if (flvjs.isSupported()) {
        if (flvPlayer) {
            flvPlayer.pause()
            flvPlayer.unload()
            flvPlayer.detachMediaElement()
            flvPlayer.destroy()
        }
        flvPlayer = flvjs.createPlayer(
        {
            type: 'flv',
            url: this.webrtcUrl
        },
        {
            cors: true,  //是否跨域
            enableWorker: true,  //是否多线程工作
            anableStashBuffer: false,  //是否启用缓存
            stashInitialSize: 384,  //缓存大小(kb) 默认384kb
            autoCleanupSourceBuffer: true  //是否自动缓存
        }
        )
        flvPlayer.attachMediaElement(document.getElementById('vId'))  // 在这里绑定元素
        flvPlayer.load()
        flvPlayer.play()
        //报错重连
        flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {
        console.log('errType:', errType)
        console.log('errorDetail:', errDetail)
        if(flvPlayer){
                destoryVideo()
                webrtcPlay()
            }
        })
    }
}`}
              ></Code>
            </span>
          </>
        }
      ></Description>
    </>
  );
};
